﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using Ripple.Providers;
using System;
using System.Net;

namespace Ripple.UnitTest.Providers
{
    [TestClass]
    public class JsonRippleProviderUnitTest
    {
        [TestMethod]
        public void AccountInfoAccountNotFound()
        {
            // Arrange
            JsonRippleProvider provider = new JsonRippleProvider(@"https://s1.ripple.com:51234");
            Assert.IsNotNull(provider);

            // Act
            AccountInfoResult result = provider.AccountInfo("unittest", "validated");

            // Assert
            Assert.IsNotNull(result);
            Assert.AreEqual("actNotFound", result.Error);
            Assert.AreEqual("Account not found.", result.Error_Message);
            Assert.AreEqual(15, result.Error_Code);
            Assert.AreEqual("error", result.Status);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void AccountInfoEmptyParm()
        {
            // Arrange
            JsonRippleProvider provider = new JsonRippleProvider(@"https://s1.ripple.com:51234");
            Assert.IsNotNull(provider);

            // Act
            AccountInfoResult result = provider.AccountInfo("", "validated");
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void AccountInfoNullParm()
        {
            // Arrange
            JsonRippleProvider provider = new JsonRippleProvider(@"https://s1.ripple.com:51234");
            Assert.IsNotNull(provider);

            // Act
            AccountInfoResult result = provider.AccountInfo(null, "validated");
        }

        [TestMethod]
        public void AccountInfoSuccess()
        {
            // Arrange
            JsonRippleProvider provider = new JsonRippleProvider(@"https://s1.ripple.com:51234");
            Assert.IsNotNull(provider);

            // Act
            AccountInfoResult result = provider.AccountInfo("r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59", "validated");

            // Assert
            Assert.IsNotNull(result);
            Assert.IsNull(result.Error);
            Assert.IsNull(result.Error_Message);
            Assert.AreEqual(0, result.Error_Code);
            Assert.AreEqual("success", result.Status);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void AccountInfoWhitespaceParm()
        {
            // Arrange
            JsonRippleProvider provider = new JsonRippleProvider(@"https://s1.ripple.com:51234");
            Assert.IsNotNull(provider);

            // Act
            AccountInfoResult result = provider.AccountInfo("   ", "validated");
        }

        [TestMethod]
        public void AccountLinesSuccess()
        {
            // Arrange
            JsonRippleProvider provider = new JsonRippleProvider(@"https://s1.ripple.com:51234");
            Assert.IsNotNull(provider);

            // Act
            AccountLinesResult result = provider.AccountLines("r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59", "validated");

            // Assert
            Assert.IsNotNull(result);
            Assert.IsNull(result.Error);
            Assert.IsNull(result.Error_Message);
            Assert.AreEqual(0, result.Error_Code);
            Assert.AreEqual("success", result.Status);
        }

        [TestMethod]
        public void AccountOffersSuccess()
        {
            // Arrange
            JsonRippleProvider provider = new JsonRippleProvider(@"https://s1.ripple.com:51234");
            Assert.IsNotNull(provider);

            // Act
            AccountOffersResult result = provider.AccountOffers("rM3X3QSr8icjTGpaF52dozhbT2BZSXJQYM", "validated");

            // Assert
            Assert.IsNotNull(result);
            Assert.IsNull(result.Error);
            Assert.IsNull(result.Error_Message);
            Assert.AreEqual(0, result.Error_Code);
            Assert.AreEqual("success", result.Status);
        }

        [TestMethod]
        public void AccountTransactionsSuccess()
        {
            // Arrange
            JsonRippleProvider provider = new JsonRippleProvider(@"https://s1.ripple.com:51234");
            Assert.IsNotNull(provider);

            // Act
            AccountTransactionsResult result = provider.AccountTransactions("rM3X3QSr8icjTGpaF52dozhbT2BZSXJQYM");

            // Assert
            Assert.IsNotNull(result);
            Assert.IsNull(result.Error);
            Assert.IsNull(result.Error_Message);
            Assert.AreEqual(0, result.Error_Code);
            Assert.AreEqual("success", result.Status);
        }

        [TestMethod]
        [ExpectedException(typeof(UriFormatException))]
        public void ConstructorInvalidUri()
        {
            JsonRippleProvider provider = new JsonRippleProvider("dummy");

            Assert.IsNotNull(provider);
        }

        [TestMethod]
        public void ConstructorUsingAppConfig()
        {
            JsonRippleProvider provider = new JsonRippleProvider();

            Assert.IsNotNull(provider);
            Assert.AreEqual(9999, provider.Uri.Port);
            Assert.AreEqual("testhost", provider.Uri.Host);
        }

        [TestMethod]
        public void PingSuccess()
        {
            // Arrange
            JsonRippleProvider provider = new JsonRippleProvider(@"https://s1.ripple.com:51234");
            Assert.IsNotNull(provider);

            // Act
            PingResult result = provider.Ping();

            // Assert
            Assert.IsNotNull(result);
            Assert.IsNull(result.Error);
            Assert.IsNull(result.Error_Message);
            Assert.AreEqual(0, result.Error_Code);
            Assert.AreEqual("success", result.Status);
        }

        [TestMethod]
        [ExpectedException(typeof(WebException))]
        public void PingUnableToConnectException()
        {
            // Arrange
            JsonRippleProvider provider = new JsonRippleProvider(@"https://s1.ripple.com:55555");
            Assert.IsNotNull(provider);

            // Act
            PingResult result = provider.Ping();
        }

        [TestMethod]
        [ExpectedException(typeof(WebException))]
        public void PingUnknownHostException()
        {
            // Arrange
            JsonRippleProvider provider = new JsonRippleProvider(@"https://unknown:123");
            Assert.IsNotNull(provider);

            // Act
            PingResult result = provider.Ping();
        }

        [TestMethod]
        public void RandomSuccess()
        {
            // Arrange
            JsonRippleProvider provider = new JsonRippleProvider(@"https://s1.ripple.com:51234");
            Assert.IsNotNull(provider);

            // Act
            RandomResult result = provider.Random();

            // Assert
            Assert.IsNotNull(result);
            Assert.IsNull(result.Error);
            Assert.IsNull(result.Error_Message);
            Assert.AreEqual(0, result.Error_Code);
            Assert.AreEqual("success", result.Status);

            Assert.IsNotNull(result.Random);
            Assert.AreNotEqual("", result.Random);
        }

        [TestMethod]
        public void ServerInfoSuccess()
        {
            // Arrange
            JsonRippleProvider provider = new JsonRippleProvider(@"https://s1.ripple.com:51234");
            Assert.IsNotNull(provider);

            // Act
            ServerInfoResult result = provider.ServerInfo();

            // Assert
            Assert.IsNotNull(result);
            Assert.IsNull(result.Error);
            Assert.IsNull(result.Error_Message);
            Assert.AreEqual(0, result.Error_Code);
            Assert.AreEqual("success", result.Status);
        }

        [TestMethod]
        public void ServerStateSuccess()
        {
            // Arrange
            JsonRippleProvider provider = new JsonRippleProvider(@"https://s1.ripple.com:51234");
            Assert.IsNotNull(provider);

            // Act
            ServerStateResult result = provider.ServerState();

            // Assert
            Assert.IsNotNull(result);
            Assert.IsNull(result.Error);
            Assert.IsNull(result.Error_Message);
            Assert.AreEqual(0, result.Error_Code);
            Assert.AreEqual("success", result.Status);
        }
    }
}